home *** CD-ROM | disk | FTP | other *** search
- //*****************************************************************************
- // C_Menu.prg
- // Menu class for OBJECT v2.03
- // Copyright (c) 1991, JHK, JHK-Software, Piestany
- // Please compile with: /N/M/W/A
- //-----------------------------------------------------------------------------
-
- #include "Set.ch"
- #include "InKey.ch"
- #include "Object.ch"
- #include "SetCurs.ch"
-
- #define nQuitRequest -9999 //quit from Menu'Process()
-
- static Cmd:=0 //last Accelerator command. (assume run last task)
- static ActiveMenu //current active menu object
-
- static Stack:=nil //stack for building menu (Menu:Data) ƒø for building
- static Count:=0 //index into Menu:Block ƒ¡ƒ> menu array.
-
- static ExistIntItems:=false //flag for add an internal items in Menu:Process
-
- create class Menu
- export:
- var Color // m->Color:Menu
- var Data // {} //menu data structure (array of MD)
- var Block // {} //code blocks for each item in menu
- var Avail // {} //availability for each item in menu
- var HotKeys // {} //{{nKey,idx},..} indexes into Menu:Data for Accelerators
- var Idx // 1 //previously selected item in bar menu
- var NewTask // nil; //maximum priority for activate this new task (NewTask is pointer into Menu:Block array)
- method New=MenuNew //o:New()
- method Init=MenuInit //o:Init()
- method Password=MenuPassword //o:Password(SelfID) //called from Menu:Process()
- method AddBar=MenuAddBar //o:AddBar(cName,bAction,bPreBlock,bPostBlock),;
- method AddMenu=MenuAddMenu //o:AddMenu(cName,nHotKey,bPreBlock,bPostBlock),;
- method AddItem=MenuAddItem //o:AddItem(cName,bAction,nHotKey,bPreBlock,bPostBlock),;
- method AddCheck=MenuAddCheck //o:AddCheck(cName,bAction,nHotKey,bPreBlock,bPostBlock),;
- method AddView=MenuAddView //o:AddView(cName,cWinName,oV,nHotKey,nVKey,nEKey,nGKey,nLKey,nIKey,nFKey,nRKey,nMKey),;
- method PopSubLevel=MenuPopSubLevel //o:PopSubLevel(),;
- method DisableItem=MenuDisableItem //o:DisableItem(nItemID,lSubMenu),;
- method EnableItem=MenuEnableItem //o:EnableItem(nItemID,lSubMenu),;
- method GetMD=MenuGetMD //o:GetMD(nItemID),; //return MD object, of this menu item
- method GetParentMD=MenuGetParentMD //o:GetParentMD(nItemID),; //return Parents MD object, of this menu item
- method Process=MenuProcess //o:Process(),;
- method BarEntry=MenuBarEntry //o:BarEntry(aAccelerators),;
- method ItemEntry=MenuItemEntry //o:ItemEntry(MD,CurSize,aAccelerators),; //must be set Cursor position!
- method Done=MenuDone //o:Done(lConfirm)
- endclass
-
-
- //*****************************************************************************
- // Menu:New() --> self
- // initialize new object
- //
- constructor MenuNew()
- ::Color:= m->Color:Menu
- ::Data:= {}
- ::Block:= {}
- ::Avail:= {}
- ::HotKeys:= {}
- ::Idx:= 1
- ::NewTask:= nil
- return(self)
-
-
- //-----------------------------------------------------------------------------
- // GetActiveMenu() --> nil
- // return last active menu
- //
- function GetActiveMenu()
- return(ActiveMenu)
-
-
- //-----------------------------------------------------------------------------
- // SetMenuCmd(new) --> nil
- // get/set menu Cmd (command)
- //
- function SetMenuCmd(new)
- return Cmd update with new
-
-
- //*****************************************************************************
- // Menu:Init() --> true
- // Initialize the menu system.
- //
- method function MenuInit()
- TestAllDbfReIndex()
- DOut(ResTxt(169))
- Cmd:=0
- object Stack of Stack init
- ActiveMenu:=self //save active menu
- SetKey(K_F10,{||(Cmd:=K_F10),StuffKey(nSwapTask)}) //menu
- return(true)
-
-
- //*****************************************************************************
- // Menu:Password(SelfID) --> true
- // Change user(s) password, (supevisor menu)
- //
- method function MenuPassword(SelfID)
- if UserNo()==1
- ChPswSup(self,SelfID)
- else
- ChPswUsr(self,SelfID)
- endif
- return(true)
-
-
- //-----------------------------------------------------------------------------
- // Menu::ChPswSup(SelfID) --> true
- // main supervisor menu
- //
- static function ChPswSup(Menu,SelfID)
- local i
- i:=Alert(ResTxt(101),ResTxt(128))
- do case
- case i==1; ChPswUsr(Menu)
- case i==2; SetUsers(Menu,SelfID)
- endcase
- return(true)
-
-
- //-----------------------------------------------------------------------------
- // Menu::SetUsers(SelfID) --> true
- // supervisor pasword table
- //
- static function SetUsers(Menu,SelfID)
- local Arr:={}
- local OldSel:=Select()
- local object AB of ABrowse
- SaveDOut(ResTxt(165))
- AB:GoodInit(ResTxt(026),-3,-3,8,2*nLenPsw+Len(ResTxt(180))+3+Max(Len(ResTxt(133)),Len(ResTxt(025)))+8)
- AB:CanSwap:=false
- AB:AddBlock(,ResTxt(023),"SYS:->SUP_ID", {|x|if(nil==x,AB:Arr[AB:N,1],AB:Arr[AB:N,1]:=x)}, {||if(AB:N>2,AB:DoGet(),StuffKey(K_RIGHT))} )
- AB:AddBlock(,ResTxt(024),"SYS:->SUP_PSW", {|x|if(nil==x,AB:Arr[AB:N,2],AB:Arr[AB:N,2]:=x)}, {||if(AB:N<>2,AB:DoGet(),Alert(ResTxt(184)))} )
- AB:AddBlock(,ResTxt(025),"SYS:->SUP_MENU", {||ResTxt(133)}, {||if(AB:N>1,Security(Menu,AB,SelfID),Alert(ResTxt(102)))} )
- AB:AddBlock(,ResTxt(180),"SYS:->SUP_LEVEL",{|x|if(nil==x,AB:Arr[AB:N,4],AB:Arr[AB:N,4]:=x)}, {||if(AB:N>1,AB:DoGet(),PauseKey())} )
- select (cBasic)
- net flock continue
- if NetErr(); AB:Done(); select (OldSel); return(true); endif
- Menu:DisableItem(SelfID)
- DbEval({||AAdd(Arr,{Convert(field->U,,false),Convert(field->P,,false),field->S,field->L})})
- select (OldSel)
- AB:Arr:=Arr
- AB:DoneBlock:={||if(SetDone(AB,SelfID),Menu:EnableItem(SelfID),false)}
- AB:InsBlock:={|AB|DoInsert(AB)}
- AB:DelBlock:={|AB|DoDelete(AB)}
- RestDOut()
- AB:Process()
- return(true)
-
-
- static function DoInsert(AB)
- local a:={}
- AAdd(a,Replicate(" ",Len(AB:Arr[1,1])))
- AAdd(a,Replicate(" ",Len(AB:Arr[1,2])))
- AAdd(a,Replicate("x",Len(AB:Arr[1,3])))
- AAdd(a,AB:Arr[2,4])
- AAdd(AB:Arr,a)
- AB:Tb:GoBottom()
- AB:Tb:Home()
- AB:Tb:RefreshAll()
- while !AB:Tb:Stabilize(); endwhile
- StuffKey(K_ENTER)
- return(true)
-
-
- static function DoDelete(AB)
- if AB:N>2 and Alert(ResTxt(105),ResTxt(123))==1
- ATrueDel(AB:Arr,AB:N)
- AB:Tb:RefreshAll()
- endif
- return(true)
-
-
- //-----------------------------------------------------------------------------
- // AB::SetDone(SelfID) --> true/false
- // save edited array into database
- //
- static function SetDone(AB,SelfID)
- local OldSel:=Select()
- SaveDOut(ResTxt(173))
- select (cBasic)
- recall all
- while LastRec()<Len(AB:Arr); DbAppend(); endwhile
- go top
- AEval(AB:Arr,{|e|SaveRec(e)})
- delete rest
- commit
- net unlock
- select (OldSel)
- RestDOut()
- return(true)
-
- static function SaveRec(e)
- field->U:=Convert(e[1],nLenPsw)
- field->P:=Convert(e[2],nLenPsw)
- field->S:=e[3]
- field->L:=e[4]
- skip
- return(true)
-
- //-----------------------------------------------------------------------------
- // Menu::Security(AB,SelfID) --> true
- // set security AB:Arr[ AB:N, 3 ] //type String250.
- //
- static function Security(Menu,AB,SelfID)
- local Arr:={}
- local i,j:=0
- local md:=Menu:Data
- local object UpAb of UpABrowse
- local OldShow:=SetDialog(true)
- local OldHelp:=SetHelpIdx(true)
- SaveDOut(ResTxt(166))
- ReadMenu(md,j,@Arr)
- j:=AWidth(Arr)+2
- for i:=1 to Len(Arr)
- Arr[i]:=StrTran(StrTran(StrTran(Arr[i],"~"),""," "),"˚"," ")
- Arr[i]:=PadR(SubStr(AB:Arr[AB:N,3],i,1)+" "+Arr[i],j)
- endfor
- UpAb:GoodInit(ResTxt(025)+": "+AllTrim(AB:Arr[AB:N,1]),-3,-3,Min(Len(Menu:Avail),MaxRow()-5))
- UpAb:AddBlock(,,"SYS:->SUP_IN_MENU",{|x|if(nil==x,UpAb:Arr[UpAb:N],UpAb:Arr[UpAb:N]:=x)}, {||DoGet(UpAb,AB,SelfID)} )
- (UpAb:Tb:GetColumn(1)):ColorBlock:={|c|if(Left(c,1)=="˚",{nNormal,nSelected},{nExtension,nUnSelect})}
- UpAb:Arr:=Arr
- UpAb:CanAppend:=false
- UpAb:Paint()
- DOut(ResTxt(154)); SetDialog(false)
- SaveHelpIdx({14}); SetHelpIdx(false)
- UpAb:Process()
- SetHelpIdx(true); RestHelpIdx(); SetHelpIdx(OldHelp)
- SetDialog(true); RestDOut(); SetDialog(OldShow)
- IEval(Len(UpAb:Arr),{|i|AB:Arr[AB:N,3]:=Stuff(AB:Arr[AB:N,3],i,1,Left(UpAb:Arr[i],1))})
- UpAb:Done()
- SetLastKey(0)
- return(true)
-
- static function ReadMenu(md,ofs,Arr)
- AEval(md,{|e|AAdd(Arr,Replicate(" ",if(ofs==0,2,ofs))+e:Name), if(!Empty(e:Data),ReadMenu(e:Data,ofs+2,@Arr),nil)})
- return(true)
-
- static function DoGet(UpAb,AB,SelfID)
- local b:=(UpAb:Tb:GetColumn(1)):Block
- local c:=Eval(b)
- local sp:=Len(c)-Len(LTrim(SubStr(c,2)))-1
- local ln:=Len(UpAb:Arr)
- clear keyboard
- if AB:N==2 and UpAb:N==SelfID
- Eval(b,"x"+SubStr(c,2)) //guest cannot change password
- else
- Eval(b,if(Left(c,1)=="˚","x","˚")+SubStr(c,2))
- endif
- UpAb:Tb:RefreshCurrent()
- UpAb:Tb:Down()
- while !UpAb:Tb:Stabilize(); endwhile
- return(true)
-
-
- //-----------------------------------------------------------------------------
- // Menu::ChPswUsr(SelfID) --> true
- // Change one (user) pasword, SelfID not used because this is non thread task.
- //
- static function ChPswUsr(Menu)
- local New1Psw,New2Psw,OldSel
- local RecN:=UserNo()
- local R:=Int(MaxRow()/2-5)
- local object UpW of UpWindow; UpW:Init(ResTxt(027),R,,8,,m->Color:Help)
- R:=Int(UpW:Row+UpW:RowSize/2-1)
- New1Psw:=New2Psw:=Replicate(" ",nLenPsw)
- UpW:Top(false)
- New1Psw:=Convert(EditItPrim(New1Psw,ResTxt(018),,R,,,"SYS:->EDIT_PSW",true),nLenPsw)
- if LastKey()==K_ESC; AbortPassword(UpW); return(false); endif
- New2Psw:=Convert(EditItPrim(New2Psw,ResTxt(019),,R,,,"SYS:->EDIT_PSW",true),nLenPsw)
- if LastKey()==K_ESC; AbortPassword(UpW); return(false); endif
- if !(New1Psw==New2Psw)
- Alert(ResTxt(119))
- else
- OldSel:=Select()
- select (cBasic)
- if NetErr()
- Alert(ResTxt(120))
- else
- go UserNo()
- net rlock continue
- if NetErr()
- Alert(ResTxt(120))
- else
- field->P:=New1Psw
- commit
- net unlock
- Alert(ResTxt(118))
- endif
- endif
- select (OldSel)
- endif
- UpW:Done()
- SetLastKey(0)
- return(true)
-
- static procedure AbortPassword(UpW)
- Alert(ResTxt(119))
- UpW:Done()
- SetLastKey(0)
- return
-
-
- //*****************************************************************************
- // Menu:AddBar(cName,bAction,bPreBlock,bPostBlock) --> true
- // Add new bar item into menu object
- //
- method function MenuAddBar(cName,bAction,bPreBlock,bPostBlock)
- local nKey
- local object MD of MD
- MD:ID:=++Count
- HelpAssoc("MENU->"+NTrim(HelpReserved(,+1)),StrTran(cName,"~"),HelpReserved())
- MD:Help:=HelpReserved()
- store value bPreBlock into MD:PreBlock
- store value bPostBlock into MD:PostBlock
- Stack:Init()
- AAdd(::Avail,false)
- MD:Name:=cName
- if Empty(bAction)
- AAdd(::Block,{Len(::Data)+1})
- MD:Data:={}
- Stack:Push(MD:Data)
- else
- AAdd(::Block,bAction)
- endif
- AAdd(::Data,MD)
- nKey:=At("~",cName)
- if nKey>0
- nKey:=c2AltKey(SubStr(cName,nKey+1,1))
- AAdd(::HotKeys,{nKey,Count})
- SetKey(nKey,{||(Cmd:=LastKey()),StuffKey(nSwapTask)}) //menu
- endif
- return(true)
-
-
- //*****************************************************************************
- // c2AltKey( Ch ) --> alt_inkey_code (this function are written in Nantucket)
- // transform char into alt inkey code
- //
- static function c2AltKey(Ch)
- local nAltKey
- static Table:={{ 65, K_ALT_A },;
- { 66, K_ALT_B },;
- { 67, K_ALT_C },;
- { 68, K_ALT_D },;
- { 69, K_ALT_E },;
- { 70, K_ALT_F },;
- { 71, K_ALT_G },;
- { 72, K_ALT_H },;
- { 73, K_ALT_I },;
- { 74, K_ALT_J },;
- { 75, K_ALT_K },;
- { 76, K_ALT_L },;
- { 77, K_ALT_M },;
- { 78, K_ALT_N },;
- { 79, K_ALT_O },;
- { 80, K_ALT_P },;
- { 81, K_ALT_Q },;
- { 82, K_ALT_R },;
- { 83, K_ALT_S },;
- { 84, K_ALT_T },;
- { 85, K_ALT_U },;
- { 86, K_ALT_V },;
- { 87, K_ALT_W },;
- { 88, K_ALT_X },;
- { 89, K_ALT_Y },;
- { 90, K_ALT_Z }}
- Ch:=Asc(Upper(Ch)) //ascii uppercase code
- nAltKey:=AScan(Table,{|x|x[1]==Ch})
- return(if(nAltKey>0, Table[nAltKey,2], 0))
-
-
- //*****************************************************************************
- // Menu:AddMenu(cName,nHotKey,bPreBlock,bPostBlock) --> true
- // Add new menu into last element in menu.
- //
- method function MenuAddMenu(cName,nHotKey,bPreBlock,bPostBlock)
- local a,Arr:={}
- local object MD of MD
- MD:ID:=++Count
- HelpAssoc("MENU->"+NTrim(HelpReserved(,+1)),StrTran(cName,"~"),HelpReserved())
- MD:Help:=HelpReserved()
- AAdd(::Avail,false)
- AAdd(::Block,nil)
- MD:Name:=" "+cName+" "
- MD:Data:={}
- store value bPreBlock into MD:PreBlock
- store value bPostBlock into MD:PostBlock
- AAdd(Stack:Top(),MD)
- Stack:Push(MD:Data)
- if nHotKey<>nil
- a:=::Data
- while !Empty(a)
- AAdd(Arr,Len(a))
- a:=ATail(a):Data
- endwhile
- ::Block[Count]:=Arr
- AAdd(::HotKeys,{nHotKey,Count})
- SetKey(nHotKey,{||(Cmd:=LastKey()),StuffKey(nSwapTask)})
- endif
- return(true)
-
-
- //*****************************************************************************
- // Menu:AddItem(cName,bAction,nHotKey,bPreBlock,bPostBlock) --> true
- // Add new item into last element in menu.
- //
- method function MenuAddItem(cName,bAction,nHotKey,bPreBlock,bPostBlock)
- local object MD of MD
- default bAction to {||nil}
- MD:ID:=++Count
- HelpAssoc("MENU->"+NTrim(HelpReserved(,+1)),StrTran(cName,"~"),HelpReserved())
- MD:Help:=HelpReserved()
- MD:Name:=" "+cName+" "
- store value bPreBlock into MD:PreBlock
- store value bPostBlock into MD:PostBlock
- AAdd(::Avail,false)
- AAdd(::Block,bAction)
- AAdd(Stack:Top(),MD)
- if nHotKey<>nil
- AAdd(::HotKeys,{nHotKey,Count})
- SetKey(nHotKey,{||(Cmd:=LastKey()),StuffKey(nSwapTask)})
- endif
- return(true)
-
-
- //*****************************************************************************
- // Menu:AddCheck(cName,bAction,nHotKey,bPreBlock,bPostBlock) --> true
- // Add new checked item into last element in menu.
- //
- method function MenuAddCheck(cName,bAction,nHotKey,bPreBlock,bPostBlock)
- local object MD of MD
- MD:ID:=++Count
- HelpAssoc("MENU->"+NTrim(HelpReserved(,+1)),StrTran(cName,"~"),HelpReserved())
- MD:Help:=HelpReserved()
- MD:CheckIt:=true
- MD:Name:=if(Eval(bAction,Count),"˚"," ")+" "+cName+" "
- store value bPreBlock into MD:PreBlock
- store value bPostBlock into MD:PostBlock
- AAdd(::Avail,false)
- AAdd(::Block,bAction)
- AAdd(Stack:Top(),MD)
- if nHotKey<>nil
- AAdd(::HotKeys,{nHotKey,Count})
- SetKey(nHotKey,{||(Cmd:=LastKey()),StuffKey(nSwapTask)})
- endif
- return(true)
-
-
- //*****************************************************************************
- // Menu:AddView(cName,cbWinName,View,nHotKey,nVKey,nEKey,nGKey,nLKey,nIKey,nFKey,nRKey,nMKey) --> true
- // shorcut for append standart view into menu
- //
- method function MenuAddView(cName,WinName,View,nHotKey,nVKey,nEKey,nGKey,nLKey,nIKey,nFKey,nRKey,nMKey)
- default WinName to View:Name
- if Stack:IsEmpty()
- ::AddBar(cName,nHotKey,{|i|View:PreGoto(self,i)},{|i|View:PostGoto(self,i)})
- else
- ::AddMenu(cName,nHotKey,{|i|View:PreGoto(self,i)},{|i|View:PostGoto(self,i)})
- endif
- ::AddItem(ResTxt(035), {|i|View:View(i,StrTran(ResTxt(035),"~")+": "+WinName)},nVKey)
- ::AddItem(ResTxt(036), {|i|View:Edit(i,StrTran(ResTxt(036),"~")+": "+WinName)},nEKey)
- ::AddItem(ResTxt(037), {||View:Goto()}, nGKey)
- ::AddItem(ResTxt(179), {||View:Locate()}, nLKey)
- ::AddMenu(ResTxt(038), nIKey, {|i,Cs|View:SetIndex(i,,,Cs)})
- ::PopSubLevel()
- ::AddMenu(ResTxt(039),nFKey, {|i,Cs|View:SetFilter(i,,,Cs)})
- ::PopSubLevel()
- ::AddMenu(ResTxt(040),nRKey, {|i,Cs|View:SetReport(i,WinName,,,Cs)})
- ::PopSubLevel()
- ::AddMenu(ResTxt(041),nMKey)
- ::AddMenu(ResTxt(042),, {|i,Cs|View:ModIndex(i,WinName,,,Cs)})
- ::PopSubLevel()
- ::AddMenu(ResTxt(043),,{|i,Cs|View:ModFilter(i,WinName,,,Cs)})
- ::PopSubLevel()
- ::AddMenu(ResTxt(044),,{|i,Cs|View:ModReport(i,WinName,,,Cs)})
- ::PopSubLevel()
- ::PopSubLevel()
- ::PopSubLevel()
- return(true)
-
-
- //*****************************************************************************
- // Menu:PopSubLevel() --> true
- // go one menu level up
- //
- method function MenuPopSubLevel()
- Stack:Pop()
- return(true)
-
-
- //*****************************************************************************
- // Menu:DisableItem(nItemID,lSubMenu) --> true
- // disable menu item
- //
- method function MenuDisableItem(nItemID,lSubMenu)
- default lSubMenu to true
- SetItem(self,nItemID,lSubMenu,false)
- return(true)
-
-
- //*****************************************************************************
- // Menu:EnableItem(nItemID,lSubMenu) --> true
- // enable menu item
- //
- method function MenuEnableItem(nItemID,lSubMenu)
- default lSubMenu to true
- SetItem(self,nItemID,lSubMenu,true)
- return(true)
-
-
- //-----------------------------------------------------------------------------
- // Menu::SetItem(nItemID,lSubMenu,lValue) --> true
- // set visibility menu item
- //
- static function SetItem(Menu,nItemID,lSubMenu,lValue)
- local md
- Menu:Avail[nItemID]:=lValue
- if lSubMenu
- md:=Menu:GetMD(nItemID)
- SetSub(Menu,md,lValue)
- endif
- return(true)
-
- static function SetSub(Menu,md,lValue)
- AEval(md:Data,{|e|Menu:Avail[e:ID]:=lValue,if(!Empty(e:Data),SetSub(Menu,e,lValue),nil)})
- return(true)
-
-
- //*****************************************************************************
- // Menu:GetMD(nItemID) --> MD object
- //return MD object, of this menu item
- //
- method function MenuGetMD(nItemID)
- local md
- ScanID(nItemID,0,@md,::Data)
- return(md)
-
- static function ScanID(nID,i,md,aData)
- return(AScan(aData,{|e| if(++i==nID,(md:=e,true),if(!Empty(e:Data),ScanID(@nID,@i,@md,e:Data)>0,false))}))
-
-
- //*****************************************************************************
- // Menu:GetParentMD(nItemID) --> parent MD object
- //return Parents MD object, of this menu item
- //
- method function MenuGetParentMD(nItemID)
- local md
- ScanParentID(nItemID,0,@md,self)
- return(md)
-
- static function ScanParentID(nID,i,md,Menu)
- return(AScan(Menu:Data,{|e| if(++i==nID,(md:=Menu,true),if(!Empty(e:Data),ScanParentID(@nID,@i,@md,e)>0,false))}))
-
-
- //*****************************************************************************
- // Menu:Process() --> true
- // main program loop
- //
- method function MenuProcess()
- local i,OldCurs
- if !ExistIntItems //...............INTERNAL HELP ITEMS......................
- HelpAssoc("SYS:->EDIT_PSW", "", HelpReserved(,+1))
- HelpAssoc("SYS:->SUP_ID", ResTxt(023), HelpReserved(,+1))
- HelpAssoc("SYS:->SUP_PSW", ResTxt(024), HelpReserved(,+1))
- HelpAssoc("SYS:->SUP_MENU", ResTxt(025), HelpReserved(,+1))
- HelpAssoc("SYS:->SUP_LEVEL", ResTxt(180), HelpReserved(,+1))
- HelpAssoc("SYS:->SUP_IN_MENU", ResTxt(191), HelpReserved(,+1))
- HelpAssoc("SYS:->IDX_NAME", ResTxt(056), HelpReserved(,+1))
- HelpAssoc("SYS:->IDX_KEY", ResTxt(061), HelpReserved(,+1))
- HelpAssoc("SYS:->IDX_UNIQ", ResTxt(063), HelpReserved(,+1))
- HelpAssoc("SYS:->FLT_NAME", ResTxt(056), HelpReserved(,+1))
- HelpAssoc("SYS:->FLT_EXPR", ResTxt(062), HelpReserved(,+1))
- HelpAssoc("SYS:->FLT_PROP", ResTxt(181), HelpReserved(,+1))
- HelpAssoc("SYS:->RPT_NAME", ResTxt(056), HelpReserved(,+1))
- HelpAssoc("SYS:->RPT_TOP", ResTxt(047), HelpReserved(,+1))
- HelpAssoc("SYS:->RPT_FIELDS", ResTxt(048), HelpReserved(,+1))
- HelpAssoc("SYS:->RPT_BOTTOM", ResTxt(049), HelpReserved(,+1))
- HelpAssoc("SYS:->RPT_ONLY", ResTxt(193), HelpReserved(,+1))
- HelpAssoc("SYS:->RPT_IN_SEL", ResTxt(082), HelpReserved(,+1))
- HelpAssoc("SYS:->RPT_IN_TITLE",ResTxt(082), HelpReserved(,+1))
- HelpAssoc("SYS:->RPT_IN_TOT", ResTxt(084), HelpReserved(,+1))
- HelpAssoc("SYS:->RPT_IN_SUBT", ResTxt(085), HelpReserved(,+1))
- HelpAssoc("SYS:->PAGE_NO", ResTxt(195), HelpReserved(,+1))
- ExistIntItems:=true
- endif
- if GetLastDbf():lNew //..............FILL THE HELP DBF.......................
- DOut(ResTxt(190))
- select (cHelp)
- for i:=1 to HelpReserved() //+20 internal items ???
- net append blank continue
- field->Text:=cr_lf+" "+ResTxt(188)
- field->ColSize:=Len(ResTxt(188))+4
- field->RowSize:=3
- endfor
- net unlock
- GetLastDbf():lNew:=false
- endif
- if UserNo()<=1 //......................PROTECTION............................
- AFill(::Avail,true)
- else
- (cBasic)->(DbGoto(UserNo()))
- IEval(Len(::Avail),{|i|::Avail[i]:=(SubStr((cBasic)->S,i,1)=="˚")})
- endif
- select (cBasic)
- Cmd:=K_F10
- @ 0,0 say Replicate(" ",MaxCol()+1) color m->Color:Menu
- DOut(ResTxt(174))
- SaveHelpIdx({16})
- repeat //......................MAIN PROGRAM LOOP.........
- OldCurs:=SetCursor(SC_NONE)
- if ::NewTask<>nil
- i:=::NewTask
- ::NewTask:=nil
- else
- if Cmd==K_F10; i:=::BarEntry({})
- elseif Cmd==0; i:=0
- else
- if (i:=AScan(::HotKeys,{|e|e[1]==Cmd}))>0 //Accelerator key not found
- i:=::HotKeys[i,2] //item_id
- if ::Avail[i] //available_item
- if ValType(::Block[i])=="A"
- i:=::BarEntry(AClone(::Block[i])) //menu entry with copy accelerators
- endif
- else
- i:=0 //item is not available
- endif
- endif
- endif
- endif
- SetCursor(OldCurs)
- SetLastKey(K_ENTER) //overwrite K_ESC (exit from menu)
- if i==0
- Cmd:=K_F10
- RestartTask()
- elseif Empty(::Block[i])
- Cmd:=K_F10
- RestartTask()
- else
- Cmd:=0
- Eval(::Block[i],i)
- endif
- until Cmd==nQuitRequest
- RestHelpIdx()
- return(true)
-
-
- //*****************************************************************************
- // Menu:BarEntry(aAccelerators) --> bAction
- // main menu loop, return bAction of selected menu item
- //
- method function MenuBarEntry(aAcc)
- local Idx,Ch,nAction,i
- SaveDOut(ResTxt(142))
- Idx:=if(!Empty(aAcc),(StuffKey(K_ENTER),ATrueDel(aAcc,1)),::Idx)
- TrueIdx(self,@Idx,0)
- nAction:=-1 //do nothing
- repeat
- ShowBar(self,Idx)
- repeat
- Ch:=GetKey(0) //MUST BE GetKey(), (do not use InkeyWait()!)
- AboutOff(true) //make something only first pass
- if Ch==K_F1
- HelpKeys()
- elseif Ch==K_SH_F1
- ReadHelpVar("MENU->"+NTrim(::Data[Idx]:Help))
- HelpField(false)
- ReadHelpVar("")
- endif
- until !(Ch==K_SH_F1)
- do case
- case Ch==K_ESC
- if !Empty(GetTList())
- nAction:=0 //restart_task
- endif
- case Ch==K_ENTER or Ch==K_DOWN
- nAction:=::ItemEntry(::Data[Idx],0,aAcc)
- if LastKey()==K_LEFT or LastKey()==K_RIGHT
- TrueIdx(self,@Idx,if(LastKey()==K_LEFT,-1,+1))
- StuffKey(K_DOWN)
- endif
- case Ch==K_LEFT
- TrueIdx(self,@Idx,-1)
- case Ch==K_RIGHT
- TrueIdx(self,@Idx,+1)
- case Ch==K_HOME
- Idx:=1
- TrueIdx(self,@Idx,0)
- case Ch==K_END
- Idx:=Len(::Data)
- TrueIdx(self,@Idx,0)
- otherwise
- Ch:=Upper(Chr(Ch))
- if "A"<=Ch and Ch<="Z"
- Ch:="~"+Ch
- if (i:=AScan(::Data,{|e|At(Ch,Upper(e:Name))>0}))>0
- Idx:=i
- StuffKey(K_ENTER)
- endif
- endif
- endcase
- until nAction>=0
- ::Idx:=Idx //save selection
- ShowBar(self,0) //hide selection
- RestDOut()
- return(nAction)
-
-
- //-----------------------------------------------------------------------------
- // Menu::TrueIdx(@Idx,nDirection) --> true
- // evaluate true Idx for bar menu, check availability of the bar item
- //
- static function TrueIdx(Menu,Idx,nDirection)
- if nDirection==0; Idx--; nDirection++; endif
- repeat
- Idx+=nDirection
- if Idx<1 and Set(_SET_WRAP); Idx:=Len(Menu:Data)
- elseif Idx>Len(Menu:Data) and Set(_SET_WRAP); Idx:=1
- elseif Idx<1; Idx:=1; if !(Menu:Avail[Menu:Data[Idx]:ID]); nDirection:=+1; endif
- elseif Idx>Len(Menu:Data); Idx:=Len(Menu:Data); if !(Menu:Avail[Menu:Data[Idx]:ID]); nDirection:=-1; endif
- endif
- until Menu:Avail[Menu:Data[Idx]:ID]
- return(true)
-
-
- //-----------------------------------------------------------------------------
- // Menu::ShowBar(Idx) --> true
- // show menu bar, check validation for current item, can change Idx.
- //
- static function ShowBar(Menu,Idx)
- local i,e,MD
- local aClr:=ListAsArray(Menu:Color)
- local object Cursor of Cursor
- AAdd(aClr,if(m->tColor==1,GetBack(aClr[nNormal]),GetFore(aClr[nNormal]))+"/"+GetBack(aClr[nEnhanced]))
- DispBegin()
- SetPos(0,0)
- DispOut(" ",aClr[nNormal])
- Cursor:Get()
- for i:=1 to Len(Menu:Data)
- e:=Menu:Data[i]
- if Idx==i; Cursor:Get(); endif
- DrawItem(e:Name,Menu:Avail[e:ID],(Idx==i),aClr)
- endfor
- Cursor:Size:=SC_NONE
- Cursor:Col--
- Cursor:Set()
- DispEnd()
- return(true)
-
-
- //-------------------------------------------
- // DrawItem(It,SelIt,HiIt) --> true
- // draw one menu items for OChoice
- //
- static function DrawItem(It,SelIt,HiIt,Clr)
- local cn,cl,i:=At("~",It)
- if m->tColor<>0
- cn:=Clr[if(SelIt,if(HiIt,nExtension,nNormal),nDisable)]
- cl:=Clr[if(SelIt,if(HiIt,nSelected,nLetter),nDisable)]
- else
- cn:=Clr[if(SelIt,if(HiIt,nSelected,nNormal),nDisable)]
- cl:=Clr[if(SelIt,nLetter,nDisable)]
- endif
- DispOut(" ",cn)
- if i>0
- DispOut(Left(It,i-1),cn)
- DispOut(SubStr(It,i+1,1),cl) //letter
- DispOut(SubStr(It,i+2),cn)
- else
- DispOut(It,cn)
- endif
- DispOut(" ",cn)
- return(true)
-
-
- //*****************************************************************************
- // Menu:ItemEntry(MD,CurSize,aAccelerator) --> nAction
- // process one menu entry
- //
- method function MenuItemEntry(MD,CurSize,aAcc)
- local Mnu,Help,Items,SelItems,nAction,lExit,i,e,Row,Col,c
- if !Eval(MD:PreBlock,MD:ID,CurSize); return(-1); endif //do nothing
- SaveDOut(ResTxt(141))
- if Empty(MD:Data)
- if LastKey()==K_ENTER //select
- if MD:CheckIt
- e:=::Block[MD:ID]
- Eval(e,MD:ID,!Eval(e,MD:ID)) //swap value
- Row:=Row() //and draw it
- Col:=Col()
- @ Row,Col-CurSize say if(Eval(e,MD:ID),"˚"," ") color ListAsArray(m->Color:Menu)[nSelected]
- SetPos(Row,Col)
- if Set(_SET_BELL); Bell(); endif
- //
- if !Empty(MD:PostBlock); Eval(MD:PostBlock,MD:ID,CurSize); endif
- return(-1) //0
- else //standart action
- if !Empty(MD:PostBlock); Eval(MD:PostBlock,MD:ID,CurSize); endif
- return(MD:ID)
- endif
- else //exit, no action?
- if !Empty(MD:PostBlock); Eval(MD:PostBlock,MD:ID,CurSize); endif
- return(-1) //do nothing
- endif
- endif
- Help:={}
- Items:={}
- SelItems:={}
- for i:=1 to Len(MD:Data)
- e:=MD:Data[i]
- if e:CheckIt
- e:Name:=if(Eval(::Block[e:ID]),"˚"," ")+SubStr(e:Name,2)
- endif
- AAdd(Help,e:Help)
- AAdd(Items,e:Name)
- AAdd(SelItems,::Avail[e:ID])
- endfor
- lExit:=false
- if !Empty(aAcc); MD:Idx:=ATrueDel(aAcc,1); lExit:=true; endif
- object Mnu of Mnu
- Mnu:Choice:=MD:Idx
- Mnu:Init(,,,CurSize,Items,SelItems,::Color)
- Mnu:Help:=Help
- repeat
- nAction:=-1
- if !lExit
- MD:Idx:=Abs(Mnu:Process())
- endif
- if Mnu:Choice>0 or (LastKey()==K_RIGHT and CurSize<>0) //down
- nAction:=::ItemEntry(e:=MD:Data[MD:Idx],AWidth(Items,{|e|Len(e)-if(At("~",e)>0,1,0)}),aAcc)
- if e:CheckIt
- c:=if(Eval(::Block[e:ID],e:ID),"˚"," ")
- Items[MD:Idx]:=c+SubStr(Items[MD:Idx],2)
- endif
- lExit:=(nAction>=0)
- else //up
- lExit:=true
- if LastKey()==nSwapTask; nAction:=0; endif
- if SetQuickEsc() and LastKey()==K_ESC; StuffKey(K_ESC); endif
- endif
- until lExit and Eval(MD:PostBlock,MD:ID,CurSize)
- Mnu:Done()
- RestDOut()
- return(nAction)
-
-
- //*****************************************************************************
- // Menu:Done() --> true/false
- // destroy this object.
- //
- method function MenuDone(lConfirm)
- local lExit:=true
- default lConfirm to true
- if lConfirm and Alert(ResTxt(097),ResTxt(123))<>1; return(false); endif
- while lExit and !Empty(GetTList()); lExit:=ATail(GetTList()):Done(); endwhile
- if lExit
- Stack:=nil
- AEval(::HotKeys,{|e|SetKey(e[1],nil)})
- SetKey(K_F10,nil)
- Cmd:=nQuitRequest
- ActiveMenu:=nil
- endif
- return(lExit)
-
- //------------------------------------------------------- eof (c)JHK ----------
-
-